<script setup lang="ts">
import { computed, ref, PropType, onBeforeMount, onBeforeUnmount, onMounted } from 'vue'
import {
  prtCount,
  Tree,
  findNodeById,
  TransData,
  findUnhiddenPrtUnderAsm,
} from '../types/tree-type'
import { ElTree } from 'element-plus'

const props = defineProps({
  defaultExpandAll: {
    type: Boolean,
    default: false,
  },
  draggable: {
    type: Boolean,
    default: true,
  },
  dataSource: {
    type: Array as PropType<Tree[]>,
    required: true,
    default: () => [],
  },
  expandOnClickNode: {
    type: Boolean,
    default: false,
  },
})

// 定义checked零件缓存
const checkTemp: Array<TransData> = []

const treeOut = ref<InstanceType<typeof ElTree>>(null)

const handleCheckChange = (data: Tree, checked: boolean) => {
  if (data.type === 'asm') {
    return
  }

  const { id, label, path } = data
  const newTrans = new TransData(id, label, path)
  console.log(newTrans)

  if (checked) {
    checkTemp.push(newTrans)
  } else {
    for (let i = 0; (i = checkTemp.length - 1); i--) {
      if ((checkTemp[i].id = data.id)) {
        checkTemp.splice(i, 1)
      }
    }
  }
}

const handleNodeDragStart = (event) => {
  event.dataTransfer.dropEffect = 'copy'

  if (checkTemp.length != 0) {
    event.dataTransfer.setData('multi', JSON.stringify(checkTemp))
  } else {
    const foundNode = findNodeById(props.dataSource, event.target.id)
    const { id, label, type, path } = foundNode
    if (type == 'asm') {
      const res: Tree[] = []
      findUnhiddenPrtUnderAsm(foundNode, res)
      console.log(res)
      if (res.length != 0) {
        checkTemp.length = 0
        res.forEach((child) => {
          const { id, label, path } = child
          const temp = new TransData(id, label, path)
          checkTemp.push(temp)
        })
      }
      event.dataTransfer.setData('multi', JSON.stringify(checkTemp))
    } else {
      const newTrans = new TransData(id, label, path)
      event.dataTransfer.setData('single', JSON.stringify(newTrans))
      return
    }
  }

  // console.log('拖放事件开始')
  // emit('node-drag-start', event)
}

// 根据id更改零件显隐状态
const hidePrtById = (id: number, status: boolean) => {
  const nodeById = findNodeById(props.dataSource, id)
  if (nodeById != null) {
    nodeById.hidden = status
  }
}

// 计算属性：未归档零件数目
const partLeft = computed(() => {
  if (!props.dataSource || props.dataSource.length === 0) {
    return 0 // 或其他默认值
  }
  return prtCount(props.dataSource[0])
})

const noDrop = () => {
  return false
}

const dragover_handler = (event) => {
  event.preventDefault()
  event.dataTransfer.dropEffect = 'none'
}

const clearTemp = () => {
  checkTemp.length = 0
}
defineExpose({
  hidePrtById,
  clearTemp,
})

// 过滤隐藏节点
// 计算属性：过滤后的数据源
const filteredDataSource = computed(() => {
  // 基于原始数据生成过滤后的数组
  return filterHiddenNodes(props.dataSource)
})

// 递归处理
const filterHiddenNodes = (nodes: Tree[]): Tree[] => {
  if (!nodes || nodes.length === 0) return []

  return nodes.reduce((result, node) => {
    // 情况1：当前节点 hidden: true → 直接剔除，不保留自身及子节点
    if (node.hidden) return result

    // 情况2：当前节点 hidden: false → 保留节点，并递归过滤子节点
    const filteredNode = { ...node } // 深拷贝，避免修改原始数据
    // 递归过滤子节点（只保留子节点中 hidden: false 的）
    filteredNode.children = filterHiddenNodes(node.children)
    // 将过滤后的节点加入结果
    result.push(filteredNode)
    return result
  }, [] as Tree[])
}
</script>

<template>
  <div>
    <!-- 直接渲染计算属性的值 -->
    <span
      >剩余的零件个数为：<span
        :style="{
          'font-weight': 'bold',
          color: partLeft == 0 ? 'green' : 'red',
        }"
        >{{ partLeft }}</span
      ></span
    >
    <!-- <button @click="console.log(props.dataSource)" style="margin-left: 10px">打印传递数据</button> -->
    <hr />
    <el-tree
      :data="filteredDataSource"
      node-key="id"
      :default-expand-all="defaultExpandAll"
      :expand-on-click-node="expandOnClickNode"
      ref="treeOut"
      show-checkbox
      @check-change="handleCheckChange"
    >
      <template #default="{ node, data }">
        <div
          class="unselectable"
          :draggable="props.draggable"
          @dragstart="handleNodeDragStart"
          :allow-drop="noDrop"
          @dragover="dragover_handler"
          :id="data.id"
        >
          {{ node.label }}
        </div>
      </template>
    </el-tree>
  </div>
</template>

<style lang="css" scoped>
#strong-text-red {
  color: red;
}

#strong-text-red {
  font-weight: bold;
  color: greenyellow;
}

.unselectable {
  user-select: none;
}
</style>
